﻿using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using Newtonsoft.Json;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.ServiceComponent.DAC.Service;
using System.Reflection;
using System.Data;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Base.Dao;

namespace T.FAS.Runtime.DataModel.Dao
{
    public class StateMachineMetadataELBDao : DaoService<StateMachineMetadata>, IStateMachineMetadataDao
    {
        #region Fields & Properties
        public const string MetaDataID = DataModelConst.StateMachineMetaType;
        public const string MetaDataName = "状态机";
        public override string TableName => "FAS_StateMachine";
        public override string IDColumnName => "ID";
        public override List<string> ExceptColumnName {get;} = DaoUtil.GetExceptionColumn<StateMachineMetadata>(
                new List<string>
                {
                    EntityTools.ProjectBranchID,
                });
        #endregion

        #region Override Funcs

        //public override Dictionary<string, object> GetDataMapping(StateMachineMetadata data)
        //{
        //    var datas = base.GetDataMapping(data);
        //    datas.Remove(nameof(data.EnableStateChangeEvent));
        //    datas.Add(nameof(data.EnableStateChangeEvent), (bool)data.EnableStateChangeEvent);
        //    return datas;
        //}

        public override StateMachineMetadata ConvertToObject(Dictionary<string, PropertyInfo> columns, DataRow row)
        {
            var myCol = new Dictionary<string, PropertyInfo>(base.Columns);
            myCol.Remove("EnableStateChangeEvent");
            var data = base.ConvertToObject(myCol, row);
            //if (row["EnableStateChangeEvent"] != null)
            //    data.EnableStateChangeEvent = int.Parse(Convert.ToString(row["EnableStateChangeEvent"])) == 0 ? false : true;

            string isEnableStateChangeEventVal = row["EnableStateChangeEvent"]?.ToString();
            if (!string.IsNullOrEmpty(isEnableStateChangeEventVal))
            {
                if (int.TryParse(isEnableStateChangeEventVal, out int isEnableStateChangeEventInt))
                {
                    data.EnableStateChangeEvent = isEnableStateChangeEventInt == 0 ? false : true;
                }
                else
                    data.EnableStateChangeEvent = false;
            }
            else
                data.EnableStateChangeEvent = false;
            return data;
        }
       
        public override Dictionary<string, PropertyInfo> GetColumns()
        {
            return DaoServiceExtension.GetAllColumns<StateMachineMetadata>(base.GetColumns());
        }
        #endregion

        public StateMachineMetadataELBDao() : base()
        {
            DBName = "TFAS";
        }

        #region 获取元数据内容
        /// <summary>
        /// 根据主键id获取状态机
        /// </summary>
        /// <param name="smId"></param>
        /// <returns></returns>
        public StateMachineMetadata GetStateMachineMetadataByID(string smId)
        {
            var StateMachineMetadata = base.GetObject(smId);
            if (StateMachineMetadata == null)
                return null;
            InitializeStateMachine(StateMachineMetadata);
            return StateMachineMetadata;
        }

        /// <summary>
        /// 根据CDOid获取状态机列表
        /// </summary>
        /// <param name="cdoId"></param>
        /// <returns></returns>
        public List<StateMachineMetadata> GetStateMachineByCDO(string cdoId)
        {
            var result = new List<StateMachineMetadata>();
            List<object> objects = base.GetObjectsByFilter($"CDOMetadataID='{cdoId}'");
            if (objects != null)
            {
                objects.ForEach(obj => result.Add(obj as StateMachineMetadata));
            }
            return result;
        }

       /// <summary>
       /// 根据CDOId,状态列获取状态机
       /// </summary>
       /// <param name="cdoId"></param>
       /// <param name="stateCol"></param>
       /// <returns></returns>
        public List<StateMachineMetadata> GetStateMachineByCDOColumn(string cdoId, string stateCol)
        {
            if (string.IsNullOrEmpty(cdoId) || string.IsNullOrEmpty(stateCol))
                return null;
            var StateMachineMetadata = new List<StateMachineMetadata>();
            var objects = this.GetObjectsByFilter($"CDOMetadataID='{cdoId}' and CDOColKey='{stateCol}'");
            if (objects == null)
                return null;
            if (objects != null)
            {
                foreach (var obj in objects)
                {
                    var machine = obj as StateMachineMetadata;
                    InitializeStateMachine(machine);
                    StateMachineMetadata.Add(machine);
                }
            }
            return StateMachineMetadata;
        }

        /// <summary>
        /// 获取元数据内容
        /// </summary>
        /// <param name="metaDataId"></param>
        /// <returns></returns>
        public List<StateMachineMetadata> GetStateMachineMetadatas(Dictionary<string, string> filter)
        {
            var result = new List<StateMachineMetadata>();
            if (filter == null)
            {
                return result;
            }
            List<object> objects = base.GetObjectsByFilter("");
            if (objects != null)
            {
                objects.ForEach(obj => result.Add(obj as StateMachineMetadata));
            }
            result.ForEach(dao => {
                //dao.States = stateMachineStateELBDao.GetTStates(dao.ID);
                InitializeStateMachine(dao);
            });
            return result;
        }

        /// <summary>
        /// 初始化StateMachine实例，填充各个子级属性
        /// </summary>
        /// <param name="sm"></param>
        private void InitializeStateMachine(StateMachineMetadata sm)
        {
            try
            {
                if (sm == null)
                    return;
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.SM.InitError, e.Message, e);
            }
        }
        #endregion

        #region 新增
        /// <summary>
        /// 保存状态机元数据
        /// </summary>
        /// <param name="sm"></param>
        public void SaveStateMachineMetadata(StateMachineMetadata sm)
        {
            try
            {
                base.Add(new List<object> { sm });
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.SM.CreateError, e.Message, e);
            }
        }

        #endregion

        #region 修改
        /// <summary>
        /// 更新状态机元数据
        /// </summary>
        /// <param name="sm"></param>
        public void UpdateStateMachineMetadata(StateMachineMetadata sm)
        {
            try
            {
                using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted}))
                {
                    DeleteStateMachineMetadata(sm.ID);
                    SaveStateMachineMetadata(sm);
                }
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.SM.UpdateError, e.Message, e);
            }
        }

        #endregion

        #region 删除
        /// <summary>
        /// 删除StateMachineMetadata
        /// </summary>
        /// <param name="smId"></param>
        public void DeleteStateMachineMetadata(string smId)
        {
            try
            {
                base.Delete(new List<string> { smId });
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.SM.DeleteError, e.Message, e);
            }
        }

        public void DeleteStateMachineMetadata(Dictionary<string, string> filter)
        {
            DeleteStateMachineMetadata(filter["ID"]);
        }
        #endregion

        #region 其它
        /// <summary>
        /// 一个CDO的状态字段只能绑定一个状态机
        /// </summary>
        /// <param name="sm"></param>
        /// <returns>true:通过校验，false:不满足唯一性校验</returns>
        public bool UniqueCheck(StateMachineMetadata sm)
        {
            var result = DB.ExecuteScalar($"select count(1) from fas_statemachine where CDOMetadataID='{sm.CDOMetadataID}' and CDOColKey='{sm.CDOColKey}'")?.ToString();
            if (int.TryParse(result, out int r))
            {
                return r == 0;
            }
            return false;
        }
        #endregion
    }
}
